/*
 * Copyright Enalean (c) 2017-2018. All rights reserved.
 *
 * Tuleap and Enalean names and logos are registrated trademarks owned by
 * Enalean SAS. All other trademarks or names are properties of their respective
 * owners.
 *
 * This file is a part of Tuleap.
 *
 * Tuleap is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Tuleap is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Tuleap. If not, see <http://www.gnu.org/licenses/>.
 */

import Gettext                             from 'node-gettext';
import { render }                          from 'mustache';
import { sprintf }                         from 'sprintf-js';
import preview_template                    from './preview.mustache';
import french_translations                 from './po/fr.po';
import { autocomplete_groups_for_select2 } from '../autocomplete-for-select2.js';

export {
    initLdapBindingPreview
};

function initLdapBindingPreview(options, callback) {
    const {
        preserve,
        button,
        preview,
        display_name,
        select
    } = options;

    const gettext_provider = new Gettext();
    gettext_provider.addTranslations('fr_FR', 'ldap-bindings', french_translations);
    gettext_provider.setLocale(select.dataset.locale);
    gettext_provider.setTextDomain('ldap-bindings');

    const select2 = autocomplete_groups_for_select2(select, {
        allowClear: true
    });
    select2.on('change', mapPreviewToChosenLdapGroup);
    preserve.addEventListener('click', mapPreviewToChosenLdapGroup);
    mapPreviewToChosenLdapGroup();

    async function mapPreviewToChosenLdapGroup() {
        button.disabled = true;

        const chosen_ldap_group = select.value;

        if (! chosen_ldap_group) {
            preview.classList.remove('shown');
            return;
        }

        removeAllChildren(preview);
        preview.classList.add('shown');
        preview.classList.add('loading');

        let users_to_add, users_to_remove, nb_not_impacted, group_not_found;
        try {
            ({ users_to_add, users_to_remove, nb_not_impacted } = await callback(chosen_ldap_group));
            group_not_found = false;
        } catch(ex) {
            users_to_add = users_to_remove = [];
            nb_not_impacted = 0;
            group_not_found = true;
        }

        preview.classList.remove('loading');

        const rendered_preview = render(
            preview_template,
            getPresenter(users_to_add, users_to_remove, display_name, chosen_ldap_group, nb_not_impacted, group_not_found)
        );
        preview.insertAdjacentHTML('beforeEnd', rendered_preview);

        button.disabled = group_not_found;
    }

    function removeAllChildren(element) {
        [...element.children].forEach(child => child.remove());
    }

    function getPresenter(users_to_add, users_to_remove, ugroup_name, chosen_ldap_group, nb_not_impacted, ldap_group_not_found) {
        const nb_to_add    = users_to_add.length;
        const nb_to_remove = users_to_remove.length;

        const title             = sprintf(gettext_provider.gettext('Binding %s to directory group %s'), ugroup_name, chosen_ldap_group);
        const nb_to_add_text    = sprintf(gettext_provider.ngettext('%d user to add.', '%d users to add.', nb_to_add), nb_to_add);
        const nb_to_remove_text = sprintf(gettext_provider.ngettext('%d user to remove.', '%d users to remove.', nb_to_remove), nb_to_remove);

        const nothing_to_do_text        = gettext_provider.gettext("There aren't any users to add nor to remove.");
        const nb_not_impacted_text      = sprintf(gettext_provider.ngettext('%d user not impacted.', '%d users not impacted.', nb_not_impacted), nb_not_impacted);
        const ldap_group_not_found_text = sprintf(gettext_provider.gettext('Directory group %s does not exist.'), chosen_ldap_group);

        return {
            title,
            nb_to_add,
            users_to_add,
            nb_to_remove,
            nb_to_add_text,
            users_to_remove,
            nb_not_impacted,
            nb_to_remove_text,
            nothing_to_do_text,
            nb_not_impacted_text,
            ldap_group_not_found,
            ldap_group_not_found_text
        };
    }
}
